#include "InsRspHeaderRecvHandlerB.h"
#include "HttpResponseHeader.h"
#include "BeginConnInsDestHandlerB.h"
#include "OriBodyRecvRelayHandler.h"
#include "InsRspHeaderSendHandler.h"
#include "GlobalContext.h"

using namespace std;
using namespace log4cplus;

Logger InsRspHeaderRecvHandlerB::log=GetLogger(LOG4CPLUS_TEXT("InsRspHeaderRecvHandlerB"));

ITransHandler::ExecuteResultCode InsRspHeaderRecvHandlerB::OnRedirectConnect(ClientContext &client,OVERLAPPED *ovl,const InsteadHttpUrl &url)
{
	client.FreeInsteadContext();
	delete client.SetCurrentHandler(new BeginConnInsDestHandlerB(url,m_oriRecvCount));
	::PostQueuedCompletionStatus(GlobalContext::Instance().IOCP(),0,static_cast<ULONG_PTR>(client.SequenceNo()),ovl);
	return ITransHandler::ExecuteOK;
}

ITransHandler::ExecuteResultCode InsRspHeaderRecvHandlerB::OnExecuteError(ClientContext &client,OVERLAPPED *ovl,ITransHandler::ExecuteResultCode executeResult)
{
	delete client.SetCurrentHandler(new OriBodyRecvRelayHandler());
	client.FreeInsteadContext();
	LOG4CPLUS_DEBUG_STR(log,LOG4CPLUS_TEXT("In RspHeaderRecvB,execute failed(free instead context),try to retranslate original server receive data."));
	::PostQueuedCompletionStatus(GlobalContext::Instance().IOCP(),m_oriRecvCount,static_cast<ULONG_PTR>(client.SequenceNo()),client.OVL());
	return ITransHandler::ExecuteOK;
}

ITransHandler::ExecuteResultCode InsRspHeaderRecvHandlerB::OnSendResponseHeader(ClientContext &client,HttpResponseHeader &headerData)
{
	unsigned int clienSequenceNo=client.SequenceNo();
	client.ReplaceDestinationWithInsteadContext();
	delete client.SetCurrentHandler(new InsRspHeaderSendHandler());
	client.SetPartialTransIndex(0);
	if(headerData.BodyIndex()<headerData.TempBuffer().size())
	{
		string::size_type size=headerData.TempBuffer().size()-headerData.BodyIndex();
		memcpy_s(client.Buffer()->buf,client.Buffer()->len,headerData.TempBuffer().c_str()+headerData.BodyIndex(),size);
		client.WeakRefBuffer()->buf=client.Buffer()->buf;
		client.WeakRefBuffer()->len=size;
		int sendResult=::WSASend(client.SrcSock(),client.WeakRefBuffer(),1,NULL,0,client.OVL(),NULL);
		int errCode=::WSAGetLastError();
		if(sendResult!=0&&errCode!=WSA_IO_PENDING)
		{
			LOG4CPLUS_ERROR_FMT(log,LOG4CPLUS_TEXT("[Client%d]Send instead server response body data failed,error code:%d."),
				clienSequenceNo,errCode);
			return ITransHandler::ExecuteFatalError;
		}
	}
	else
	{
		::PostQueuedCompletionStatus(GlobalContext::Instance().IOCP(),client.Buffer()->len+1,static_cast<ULONG_PTR>(client.SequenceNo()),client.OVL());
	}
	return ITransHandler::ExecuteOK;
}